home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1999 #2 / Amiga Plus CD - 1999 - No. 2.iso / System-Boost / Workbench / ToolManager / Source / Library / cmdline.c < prev    next >
C/C++ Source or Header  |  1998-06-17  |  6KB  |  258 lines

  1. /*
  2.  * cmdline.c  V3.1
  3.  *
  4.  * ToolManager library command line builder
  5.  *
  6.  * Copyright (C) 1990-98 Stefan Becker
  7.  *
  8.  * This source code is for educational purposes only. You may study it
  9.  * and copy ideas or algorithms from it for your own projects. It is
  10.  * not allowed to use any of the source codes (in full or in parts)
  11.  * in other programs. Especially it is not allowed to create variants
  12.  * of ToolManager or ToolManager-like programs from this source code.
  13.  *
  14.  */
  15.  
  16. #include "toolmanager.h"
  17.  
  18. struct Parameter {
  19.  struct Parameter *p_Next;
  20.  ULONG             p_Length;
  21.  char              p_Data[1];
  22.  /* Rest of string follows here */
  23. };
  24. #define BUFLEN 256
  25.  
  26. /* Convert WB Args */
  27. #undef  DEBUGFUNCTION
  28. #define DEBUGFUNCTION ConvertWBArgs
  29. static struct Parameter *ConvertWBArgs(struct AppMessage *msg, BPTR curdir)
  30. {
  31.  struct Parameter  anchor = { NULL };
  32.  char             *buf;
  33.  
  34.  CMDLINE_LOG(LOG2(WBArgs, "Num %ld List 0x%08lx",
  35.              msg->am_NumArgs, msg->am_ArgList))
  36.  
  37.  /* Allocate conversion buffer */
  38.  if (buf = GetMemory(BUFLEN)) {
  39.   struct Parameter *p  = &anchor;
  40.   struct WBArg     *wa;
  41.   ULONG             i;
  42.  
  43.   CMDLINE_LOG(LOG1(Buf, "0x%08lx", buf))
  44.  
  45.   /* Scan WBArgs list */
  46.   for (i = msg->am_NumArgs, wa = msg->am_ArgList; i > 0; i--, wa++) {
  47.  
  48.    CMDLINE_LOG(LOG3(Next WBArg, "Lock 0x%08lx Name '%s' (0x%08lx)",
  49.                     wa->wa_Lock, wa->wa_Name, wa->wa_Name))
  50.  
  51.    /* Valid lock? */
  52.    if (wa->wa_Lock) {
  53.     char  *name;
  54.     char  *space;
  55.     ULONG  length;
  56.  
  57.     /* File or Drawer? */
  58.     if (*(wa->wa_Name) != '\0') {
  59.  
  60.      CMDLINE_LOG(LOG0(File))
  61.  
  62.      /* File. In the same directory as the program? */
  63.      if (SameLock(curdir, wa->wa_Lock) == LOCK_SAME) {
  64.  
  65.       /* Yes, just copy name */
  66.       name = wa->wa_Name;
  67.  
  68.      } else {
  69.  
  70.       /* No, build full pathname */
  71.       if ((NameFromLock(wa->wa_Lock, buf, BUFLEN) == 0) ||
  72.           (AddPart(buf, wa->wa_Name, BUFLEN) == 0))
  73.  
  74.        /* Couldn't build path name */
  75.        continue;
  76.  
  77.       /* Name is in conversion buffer */
  78.       name = buf;
  79.      }
  80.  
  81.     } else {
  82.  
  83.      CMDLINE_LOG(LOG0(Drawer))
  84.  
  85.      /* Drawer, convert lock to name */
  86.      if (NameFromLock(wa->wa_Lock, buf, BUFLEN) == FALSE) continue;
  87.  
  88.      /* Name is in conversion buffer */
  89.      name = buf;
  90.     }
  91.  
  92.     /* Get parameter length plus seperator */
  93.     length = strlen(name) + 1;
  94.  
  95.     /* Handle special case: space in name -> Quotes must be added */
  96.     if (space = strchr(name, ' ')) length += 2;
  97.  
  98.     CMDLINE_LOG(LOG3(Next Parameter, "'%s' (%ld) Alloc %ld",
  99.                      name, length - 1, sizeof(struct Parameter) + length))
  100.  
  101.     /* Allocate memory for parameter */
  102.     if (p->p_Next = GetVector(sizeof(struct Parameter) + length)) {
  103.      char *s;
  104.  
  105.      /* Initialize pointers */
  106.      p = p->p_Next;
  107.      s = p->p_Data;
  108.  
  109.      /* Initialize structure */
  110.      p->p_Next   = NULL;
  111.      p->p_Length = length;
  112.  
  113.      /* Build parameter: Seperator, (Quote), Name, (Quote) */
  114.      *s++ = ' ';
  115.      if (space) *s++ = '\"';
  116.      strcpy(s, name);
  117.      if (space) {
  118.       s    += length - 3;
  119.       *s++ =  '\"';
  120.       *s   =  '\0';
  121.      }
  122.     }
  123.    }
  124.   }
  125.  
  126.   /* Free conversion buffer */
  127.   FreeMemory(buf, BUFLEN);
  128.  }
  129.  
  130.  /* Return pointer to first parameter */
  131.  return(anchor.p_Next);
  132. }
  133.  
  134. /* Build a command line from command and WB arguments */
  135. #undef  DEBUGFUNCTION
  136. #define DEBUGFUNCTION BuildCommandLine
  137. char *BuildCommandLine(const char *cmd, struct AppMessage *msg, BPTR curdir,
  138.                        ULONG *cmdlen)
  139. {
  140.  ULONG             length = 0;
  141.  struct Parameter *params = NULL;
  142.  char             *subst  = cmd;
  143.  char             *rc     = NULL;
  144.  
  145.  CMDLINE_LOG(LOG3(Arguments, "Cmd '%s' Msg 0x%08lx CD 0x%08lx",
  146.                   cmd, msg, curdir))
  147.  
  148.  /* Build command parameter from WBArgs (if any) */
  149.  if (msg && msg->am_NumArgs && (params = ConvertWBArgs(msg, curdir))) {
  150.   struct Parameter *p = params;
  151.  
  152.   /* Calculate command line length */
  153.   do {
  154.  
  155.    /* Add parameter length */
  156.    length += p->p_Length;
  157.  
  158.    /* Next parameter */
  159.   } while (p = p->p_Next);
  160.  
  161.   CMDLINE_LOG(LOG1(Param Length, "%ld", length))
  162.  }
  163.  
  164.  /* Add command name length to total length */
  165.  length += strlen(cmd);
  166.  
  167.  /* Scan command string for [] parameter place holder */
  168.  while (subst = strchr(subst, '['))
  169.  
  170.   /* Place holder found? */
  171.   if (subst[1] == ']') {
  172.  
  173.    /* Yes, correct command line length */
  174.    length -= 2;
  175.  
  176.    /* Leave loop */
  177.    break;
  178.  
  179.   } else
  180.  
  181.    /* No, scan for next occurence */
  182.    subst++;
  183.  
  184.  CMDLINE_LOG(LOG2(CmdLine, "Len %ld Placeholder %s",
  185.                   length, subst != NULL ? "Yes" : "No"))
  186.  
  187.  /* Allocate command line (plus string terminator) */
  188.  if (rc = GetVector(length + 1)) {
  189.   char *s = rc;
  190.  
  191.   /* Copy command. Parameter placeholder? */
  192.   if (subst) {
  193.    ULONG len = subst - cmd;
  194.  
  195.    /* Yes, copy only first part of command */
  196.    strncpy(s, cmd, len);
  197.  
  198.    /* Correct pointers */
  199.    s     += len;
  200.    subst += 2;
  201.  
  202.   } else {
  203.  
  204.    /* No, just copy command */
  205.    strcpy(s, cmd);
  206.  
  207.    /* Correct pointer */
  208.    s += strlen(s);
  209.   }
  210.  
  211.   /* Scan parameter list */
  212.   {
  213.    struct Parameter *p = params;
  214.  
  215.    while (p) {
  216.  
  217.     CMDLINE_LOG(LOG1(Add Parameter, "'%s'", p->p_Data))
  218.  
  219.     /* Copy parameter */
  220.     strcpy(s, p->p_Data);
  221.  
  222.     /* Correct pointer */
  223.     s += p->p_Length;
  224.  
  225.     /* Next parameter */
  226.     p = p->p_Next;
  227.    }
  228.   }
  229.  
  230.   /* Parameter substitution? Copy rest of command */
  231.   if (subst) strcpy(s, subst);
  232.  
  233.   /* Copy length to variable */
  234.   if (cmdlen) *cmdlen = length;
  235.  
  236.   CMDLINE_LOG(LOG1(Final, "%s", rc))
  237.  }
  238.  
  239.  /* Free parameters */
  240.  {
  241.   struct Parameter *p, *np = params;
  242.  
  243.   /* Scan list */
  244.   while (p = np) {
  245.  
  246.    /* Get next parameter */
  247.    np = p->p_Next;
  248.  
  249.    /* Free parameter */
  250.    FreeVector(p);
  251.   }
  252.  }
  253.  
  254.  CMDLINE_LOG(LOG1(Result, "0x%08lx", rc))
  255.  
  256.  return(rc);
  257. }
  258.